package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;

    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;

    @Autowired
    private BaseAttributeMapper baseAttributeMapper;


    /**
     * 查询所有分类（1、2、3级分类）
     * tips:数据从封装分类视图中获取，在业务代码中进行业务处理
     * TODO:后续将读多写少放入Redis缓存中
     *
     * @return
     */
    @Override
    @GuiGuCache(prefix = "baseCategoryList:")
    public List<JSONObject> getBaseCategoryList() {
        //1.创建目标集合对象
        List<JSONObject> allList = new ArrayList<>();

        //2.查询分类视图得到所有分类数据 共计401条记录
        List<BaseCategoryView> allCategoryList = baseCategoryViewMapper.selectList(null);

        //3.处理一级分类，对所有分类数据根据-根据一级分类ID分组
        //3.1 采用Stream流进行集合分组，得到Map集合，Map中key:1级分类ID Map中Value：1级分类集合
        Map<Long, List<BaseCategoryView>> category1Map =
                allCategoryList.stream()
                        .collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
        if (CollectionUtil.isNotEmpty(category1Map)) {
            for (Map.Entry<Long, List<BaseCategoryView>> entry1 : category1Map.entrySet()) {
                //每遍历一次处理一个一级分类
                //3.2 获取一级分类ID 以及 名称
                Long category1Id = entry1.getKey();
                String category1Name = entry1.getValue().get(0).getCategory1Name();
                //3.3 构建一级分类JSON对象
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("categoryId", category1Id);
                jsonObject1.put("categoryName", category1Name);
                //4.在某个一级分类内，处理二级分类，对一级分类集合根据二级分类ID分组
                Map<Long, List<BaseCategoryView>> category2Map = entry1.getValue().stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
                //4.2 对某个一级分类集合按照二级分类ID进行分组 得到二级分类Map Map-key 二级分类ID Map-Value 二级分类集合
                if (CollectionUtil.isNotEmpty(category2Map)) {
                    List<JSONObject> jsonObject2List = new ArrayList<>();
                    for (Map.Entry<Long, List<BaseCategoryView>> entry2 : category2Map.entrySet()) {
                        //4.3 获取二级分类ID 以及 名称
                        Long category2Id = entry2.getKey();
                        String category2Name = entry2.getValue().get(0).getCategory2Name();
                        //4.4 遍历构建二级分类JSON对象 将二级分类对象加入到集合中
                        JSONObject jsonObject2 = new JSONObject();
                        jsonObject2.put("categoryId", category2Id);
                        jsonObject2.put("categoryName", category2Name);
                        //5.TODO 在某个二级分类内，处理三级分类
                        //5.1 遍历二级分类Map中Value
                        List<JSONObject> jsonObject3List = new ArrayList<>();
                        for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                            //5.2 获取三级分类ID跟名称
                            Long category3Id = baseCategoryView.getCategory3Id();
                            String category3Name = baseCategoryView.getCategory3Name();
                            //5.3 构建三级分类JSON对象
                            JSONObject jsonObject3 = new JSONObject();
                            jsonObject3.put("categoryId", category3Id);
                            jsonObject3.put("categoryName", category3Name);
                            jsonObject3List.add(jsonObject3);
                        }
                        //5.4 将构建三级分类集合放入二级分类对象中"categoryChild"属性中
                        jsonObject2.put("categoryChild", jsonObject3List);
                        jsonObject2List.add(jsonObject2);
                    }
                    //4.5 将二级分类集合放入一级分类对象中"categoryChild"中
                    jsonObject1.put("categoryChild", jsonObject2List);
                }
                //3.4 将一级分类对象加入到所有目标集合对象中
                allList.add(jsonObject1);
            }
        }
        return allList;
    }

    /**
     * 根据一级分类Id获取分类（标签名包含标签值） 列表
     *
     * @param category1Id 1级分类ID
     * @return
     */
    @Override
    @GuiGuCache(prefix = "category1Id:attributes:")
    public List<BaseAttribute> getAttributesByCategory1Id(Long category1Id) {
        //调用持久层动态SQL完成一对多查询
        return baseAttributeMapper.getAttributesByCategory1Id(category1Id);
    }

    /**
     * 根据三级分类ID查询分类视图
     *
     * @param category3Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "category3View:")
    public BaseCategoryView getCategoryView(Long category3Id) {
        return baseCategoryViewMapper.selectById(category3Id);
    }


    /**
     * 查询指定1级分类下置顶前7个三级分类集
     *
     * @param category1Id 1级分类ID
     * @return
     */
    @Override
    @GuiGuCache(prefix = "baseCategory3Top7:")
    public List<BaseCategory3> getTop7BaseCategory3(Long category1Id) {
        //1.根据一级分类ID查询二级分类集合，得到二级分类ID集合
        LambdaQueryWrapper<BaseCategory2> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseCategory2::getCategory1Id, category1Id);
        queryWrapper.select(BaseCategory2::getId);
        List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(baseCategory2List)) {
            List<Long> baseCategory2IdList = baseCategory2List.stream().map(baseCategory2 -> baseCategory2.getId()).collect(Collectors.toList());
            //2.根据二级分类ID集合查询三级分类列表获取置顶前7个三级分类集合
            LambdaQueryWrapper<BaseCategory3> baseCategory3LambdaQueryWrapper = new LambdaQueryWrapper<>();
            //2.1 查询二级分类下包含三级分类
            baseCategory3LambdaQueryWrapper.in(BaseCategory3::getCategory2Id, baseCategory2IdList);
            //2.2 查询需要置顶的三级分类
            baseCategory3LambdaQueryWrapper.eq(BaseCategory3::getIsTop, 1);
            //2.3 根据序号排序 升序排
            baseCategory3LambdaQueryWrapper.orderByAsc(BaseCategory3::getOrderNum);
            //2.4 截取前7个 SQL+limit 7
            baseCategory3LambdaQueryWrapper.last("limit 7");
            return baseCategory3Mapper.selectList(baseCategory3LambdaQueryWrapper);
        }
        return null;
    }

    /**
     * 根据1级分类对象查询包含二级分类（包含三级分类）
     *
     * @param category1Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "baseCategoryListByCategory1Id:")
    public JSONObject getBaseCategoryListByCategory1Id(Long category1Id) {
        //1.根据1级分类ID查询分类视图得到一级分类列表
        LambdaQueryWrapper<BaseCategoryView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseCategoryView::getCategory1Id, category1Id);
        List<BaseCategoryView> baseCategory1List = baseCategoryViewMapper.selectList(queryWrapper);
        //2.处理一级分类对象 封装一级分类对象包含ID，分类名称
        if (CollectionUtil.isNotEmpty(baseCategory1List)) {
            //2.1 构建一级分类对象 封装ID，名称
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("categoryId", baseCategory1List.get(0).getCategory1Id());
            jsonObject1.put("categoryName", baseCategory1List.get(0).getCategory1Name());
            //3.处理一级分类下二级分类
            //3.1 将一级分类集合再按照二级分类ID分组得到Map Map中key:二级分类ID，Map中Value二级分类集合
            Map<Long, List<BaseCategoryView>> category2Map = baseCategory1List.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //3.2 遍历Map每遍历一次Map封装二级分类JSON对象
            List<JSONObject> jsonObject2List = new ArrayList<>();
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : category2Map.entrySet()) {
                //3.3 构建二级分类对象，封装二级分类ID及名称
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("categoryId", entry2.getKey());
                jsonObject2.put("categoryName", entry2.getValue().get(0).getCategory2Name());
                jsonObject2List.add(jsonObject2);
                //4.处理二级分类下三级分类
                //4.1 遍历二级分类列表，没遍历一条记录构建三级分类对象
                List<JSONObject> jsonObject3List = new ArrayList<>();
                for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                    //4.2 构建三级分类对象，封装三级分类ID名称
                    JSONObject jsonObject3 = new JSONObject();
                    jsonObject3.put("categoryId", baseCategoryView.getCategory3Id());
                    jsonObject3.put("categoryName", baseCategoryView.getCategory3Name());
                    jsonObject3List.add(jsonObject3);
                }
                //4.3 将三级分类集合放入二级分类对象中
                jsonObject2.put("categoryChild", jsonObject3List);
            }
            //3.3 将二级分类集合放入一级分类对象中
            jsonObject1.put("categoryChild", jsonObject2List);
            return jsonObject1;
        }
        return null;
    }
}
